import React, { createRef, PureComponent } from 'react'
import { Alert, Button, DatePicker, Form, message, Modal, Popconfirm, Radio, Select, Space } from 'antd'
import { connect, history } from '@umijs/max'
import _ from 'lodash'
import moment from 'moment'
import { BreadcrumbBar, InputSearch, Logger, ProTable, ProTableOperate, ProTableOptions } from '@/components'
import { queryRestartReq, realtimeRunningCheckpoints, realtimeRunningContinue, realtimeRunningSavepoint } from './api'
import styles from './index.less'

const { Option } = Select
const { OperateItem } = ProTableOperate

const menus = [{ name: '实时计算' }, { name: '任务运维' }]

@connect(({ operationRealTime }) => ({ ...operationRealTime }))

class Operation extends PureComponent {
  constructor(props) {
    super(props)
    this.state = {
      columns: [
        {
          title: '任务名称',
          dataIndex: 'taskName',
          key: 'taskName',
          width: '15%',
          render: (taskName, record) => (
            <span className={styles.link} onClick={() => { this.queryGetParentType(record?.nodeId, taskName) }}>{taskName}</span>
          ),
        },
        {
          title: '任务状态',
          dataIndex: 'status',
          key: 'status',
          width: '8%',
          render: (status) => (
            <>
              {
                status === 1 && (
                  <><i className="iconfont icon-yunhangzhong_1 hu-blue" /> 运行中</>
                )
              }
              {
                status === 2 && (
                  <><i className="iconfont icon-chenggong hu-green" /> 成功</>
                )
              }
              {
                status === 3 && (
                  <><i className="iconfont icon-shibai1 hu-red" /> 失败</>
                )
              }
              {
                status === 4 && (
                  <><i className="iconfont icon-weiyunhang hu-gray" /> 停止</>
                )
              }
              {
                status === 5 && (
                  <><i className="iconfont icon-shibai1 hu-red" /> 暂停</>
                )
              }
            </>
          ),
        },
        {
          title: '任务类型',
          dataIndex: 'execType',
          key: 'execType',
          width: '8%',
          render: (execType) => (
            <>
              {execType === 0 && '手动执行'}
              {execType === 1 && '周期执行'}
            </>
          ),
        },
        {
          title: '启动时间',
          dataIndex: 'startTime',
          key: 'startTime',
          width: '13%',
        },
        {
          title: '结束时间',
          dataIndex: 'endTime',
          key: 'endTime',
          width: '13%',
          render: (endTime) => (
            endTime || '-'
          ),
        },
        {
          title: '运行时长(S)',
          dataIndex: 'expendTime',
          key: 'expendTime',
          width: '8%',
        },
        {
          title: '调度类型',
          dataIndex: 'scheduleType',
          key: 'scheduleType',
          width: '8%',
          render: (scheduleType) => (
            <span>{['每天', '周一至周五'][scheduleType] || '-'}</span>
          ),
        },
        {
          title: '责任人',
          dataIndex: 'userName',
          key: 'userName',
          width: '8%',
        },
        {
          title: '操作',
          key: 'action',
          width: '18%',
          render: (record) => {
            const {
              id, nodeId, status, canReRun, haveChildren,
            } = record
            return (
              <ProTableOptions size={4}>
                <span onClick={() => {
                  history.push(`/data-development/realTime/operation-detail?jobId=${id}`)
                }}
                >
                  详情
                </span>
                <span onClick={() => {
                  this.setState({
                    loggerList: [],
                  })
                  this.logRef.current.iconUpFn()
                  this.viewLog(id, this.state.offsets, false)
                }}
                >
                  日志
                </span>
                {status === 4 || status === 3 ? (
                  <span onClick={() => {
                    this.setState(
                      {
                        runShow: true,
                        confirmLoading: false,
                        id,
                      },
                      () => {
                        this.realtimeRunningCheckpoints(record)
                        this.realtimeRunningSavepoint(record)
                      },
                    )
                  }}
                  >
                    续跑
                  </span>
                ) : null}
                {status === 3 ? (
                  <span onClick={() => {
                    this.setState({
                      loggerList: [],
                    })
                    this.runningRetry(id, true)
                  }}
                  >
                    重试
                  </span>
                ) : null}
                {status === 4 ? (
                  <span>
                    {record.kafkaSourceTables ? (
                      <span
                        onClick={() => {
                          this.setState({
                            rerunShow: true,
                            id: record.id,
                            confirmLoading: false,
                            kafkaSourceTables: record.kafkaSourceTables,
                          })
                        }}
                      >
                        重跑
                      </span>
                    ) : (
                      <Popconfirm
                        title={
                          <div className="popconfirm_title">
                            重跑，则任务将丢弃停止前的状态，重新运行，若存在启停策略，将恢复自动启停
                          </div>
                        }
                        okText="确定"
                        cancelText="取消"
                        onConfirm={() => {
                          this.realtimeRunningRestart(0)
                        }}
                      >
                        <span
                          onClick={() => {
                            this.setState({
                              id: record.id,
                              confirmLoading: false,
                            })
                          }}
                        >
                          重跑
                        </span>
                      </Popconfirm>
                    )}
                  </span>
                ) : null}
                {status === 1 ? (
                  <span onClick={() => {
                    this.setState({
                      loggerList: [],
                    })
                    this.stopRun(id, true)
                  }}
                  >
                    停止
                  </span>
                ) : null}
              </ProTableOptions>
            )
          },
        },
      ],
      taskStatus: null,
      execType: null,
      nodeName: '',
      query: {
        // taskStatus: -1,
      },
      forceUpdate: 0,
      failedNum: 0,
      runningNum: 0,
      stoppedNum: 0,
      loggerList: [],
      tableTimes: [],
      rerunRadio: 1,
      loading: false,
      isHideLogger: true,
      savepoint: false,
      runRadio: 1,
      point: [],
      kafkaSourceTables: null,
    }
    this.tableRef = createRef()
    this.logRef = createRef()
  }

  componentDidMount() {
    this.querySummary()
  }

  queryGetParentType = (nodeId, nodeName) => {
    history.push(`/data-development/realTime/realTime-development?nodeId=${nodeId}&nodeName=${nodeName}`)
  }

  querySummary = () => {
    this.props.dispatch({
      type: 'operationRealTime/querySummary',
      cb: (res) => {
        const {
          failedNum, runningNum, stoppedNum,
        } = res || {}
        this.setState({
          failedNum,
          runningNum,
          stoppedNum,
        })
      },
    })
  }

  runningRetry = (id, bool) => {
    this.setState({ loading: true })
    this.props.dispatch({
      type: 'operationRealTime/runningRetry',
      params: {
        id,
      },
      cb: (res) => {
        const { status, msg } = res || {}
        this.setState({
          loading: false,
        })
        this.querySummary()
        if (status === 200) {
          message.success('操作成功')
          this.viewLog(id, 0, bool)
          this.fetchData(false)
        } else {
          message.error(msg || '系统异常，请稍后重试~')
        }
      },
    })
  }

  // 查看日志
  viewLog = (jobId, offsets, bool) => {
    clearInterval(this.time)
    this.setState({
      loading: true,
      isHideLogger: false,
      loggerList: [],
    })
    this.props.dispatch({
      type: 'operationRealTime/queryLog',
      params: {
        id: jobId,
        offset: offsets || 0, // 参考老版本，传了固定值
      },
      cb: (res) => {
        const { status, msg, data } = res || {}
        this.setState({
          loading: false,
        })
        if (status === 200) {
          this.setState((prevState) => ({
            loggerList: prevState.loggerList.concat(data?.logContent),
          }))
          // this.time = setInterval(() => {
          //   if (data?.logEnd && bool) {
          //     // this.fetchData()
          //     clearInterval(this.time)
          //   } else if (data?.logEnd) {
          //     clearInterval(this.time)
          //   } else {
          //     // this.fetchLogger(jobId, data?.offset, bool)
          //     this.viewLog(jobId, data?.offset, bool)
          //   }
          // }, 4000)
        } else {
          message.error(msg || '系统异常，请稍后重试~')
        }
      },
    })
  }

  // 重跑
  realtimeRunningRestart = async (type) => {
    this.setState({
      confirmLoading: true,
    })
    queryRestartReq({
      id: this.state.id,
      tableTimes: this.state.tableTimes,
      type,
    }).then((res) => {
      if (res.status === 200) {
        this.fetchData()
        this.setState({
          rerunShow: false,
          confirmLoading: false,
        })
        this.viewLog(this.state.id, this.state.offsets, false)
      } else {
        this.setState({
          confirmLoading: false,
        })
      }
    })
  };

  // 终止运行
  stopRun = (jobId, bool) => {
    this.setState({ loading: true })
    this.props.dispatch({
      type: 'operationRealTime/queryStop',
      params: {
        id: jobId,
      },
      cb: (res) => {
        this.setState({ loading: false })
        this.querySummary()
        const { status, msg } = res
        if (status === 200) {
          message.success('操作成功')
          this.viewLog(jobId, 0, bool)
          this.fetchData(false)
        } else {
          message.error(msg || '系统异常，请稍后重试~')
        }
      },
    })
  };

  fetchData = (isReset = true) => {
    const {
      taskStatus, nodeName, execType, query,
    } = this.state
    isReset && this.tableRef?.current?.resetPageNum()
    const tempQuery = {}
    tempQuery.nodeName = nodeName
    execType !== null && execType !== undefined && (tempQuery.execType = execType)
    taskStatus !== null && taskStatus !== undefined && (tempQuery.taskStatus = taskStatus)

    const queryTemp = _.cloneDeep(query)
    delete queryTemp.pageNum
    delete queryTemp.pageSize

    this.setState({
      query: {
        ...queryTemp,
        ...tempQuery,
      },
    })
  }

  realtimeRunningCheckpoints = (record) => {
    realtimeRunningCheckpoints({ id: record.id }).then((res) => {
      if (res.status === 200) {
        this.setState({
          point: res.data && res.data.length ? res.data : null,
        })
      }
    })
  };

  realtimeRunningSavepoint = (record) => {
    realtimeRunningSavepoint({ id: record.id }).then((res) => {
      if (res.status === 200) {
        this.setState({
          savepoint: res.data,
        })
      }
    })
  };

  realtimeRunningContinue = async () => {
    this.setState({
      confirmLoading: true,
    })
    realtimeRunningContinue({
      id: this.state.id,
      point:
        this.state.runRadio === 1
          ? this.state.savepoint && this.state.savepoint.point
          : this.state.checkPoint,
    }).then((res) => {
      if (res.status === 200) {
        this.setState({
          runShow: false,
          confirmLoading: false,
        })
        this.fetchData()
        this.viewLog(this.state.id, this.state.offsets, false)
      } else {
        this.setState({
          confirmLoading: false,
        })
      }
    })
  };

  render() {
    const {
      taskStatus, execType, loading, forceUpdate, query, columns, failedNum, runningNum, stoppedNum, loggerList,
      isHideLogger, nodeName, savepoint, runRadio, checkPoint, point, tableTimes, rerunRadio, kafkaSourceTables,
    } = this.state
    return (
      <div className={`${styles.operation} ${styles.page_content_with_breadcrumb} ${styles.page_content_tabs_height}`}>
        <BreadcrumbBar menu={menus} />
        <div className={styles.page_content_column}>
          <div className={`${styles.page_content_right} ${styles.page_content_right_flex}`}>
            <div className={styles.data_show}>
              <div className={styles.item}>
                <div><span className={styles.column}>失败数</span> <span className={styles.count}>{failedNum}</span></div>
                <i className="iconfont-colour2 icon-shibai_1" />
              </div>
              <div className={styles.item}>
                <div><span className={styles.column}>运行中</span> <span className={styles.count}>{runningNum}</span></div>
                <i className="iconfont-colour2 icon-yunhangzhong" />
              </div>
              <div className={styles.item}>
                <div><span className={styles.column}>停止数</span> <span className={styles.count}>{stoppedNum}</span></div>
                <i className="iconfont-colour2 icon-tingzhi_1" />
              </div>
            </div>
            <ProTableOperate style={{ marginBottom: 12 }}>
              <OperateItem>
                <span>任务状态</span>
                <Select
                  allowClear
                  value={taskStatus}
                  onChange={(value) => {
                    this.setState({
                      taskStatus: value || '',
                    }, () => { this.fetchData() })
                  }}
                >
                  <Option value={1}>运行中</Option>
                  <Option value={3}>失败</Option>
                  <Option value={4}>停止</Option>
                  <Option value={5}>暂停</Option>
                </Select>
              </OperateItem>
              <OperateItem>
                <span>任务类型</span>
                <Select
                  allowClear
                  value={execType}
                  onChange={(value) => {
                    this.setState({
                      execType: value || '',
                    }, () => { this.fetchData() })
                  }}
                >
                  <Option value="1">周期执行</Option>
                  <Option value="0">手动执行</Option>
                </Select>
              </OperateItem>
              <OperateItem>
                <InputSearch
                  value={nodeName}
                  placeholder="请输入任务名称进行搜索"
                  onChange={(e) => {
                    this.setState({
                      nodeName: e.target.value,
                    })
                  }}
                  onSearch={this.fetchData}
                />
              </OperateItem>
            </ProTableOperate>
            <ProTable
              ref={this.tableRef}
              loading={loading}
              key={forceUpdate}
              url="/api/v1/flink/record/running/list"
              query={query}
              rowKey="id"
              columns={columns}
            />
          </div>
          <Logger
            ref={this.logRef}
            className={`${isHideLogger ? styles.hideLogger : ''}`}
            list={loggerList || []}
          />
        </div>
        <Modal
          destroyOnClose
          title="重跑任务"
          confirmLoading={this.state.confirmLoading}
          visible={this.state.rerunShow}
          cancelText="取消"
          okText="确定"
          onOk={() => {
            this.realtimeRunningRestart(rerunRadio)
          }}
          onCancel={() => {
            this.setState({
              rerunShow: false,
            })
          }}
        >
          <div className="real-time-modal">
            <Alert
              message="重跑，则任务将丢弃停止前的状态，重新运行，若存在启停策略，将恢复自动启停"
              type="warning"
            />
            <Radio.Group
              onChange={(e) => {
                if (e.target.value === 1) {
                  this.setState({
                    tableTimes: [],
                  })
                }
                this.setState({
                  rerunRadio: e.target.value,
                })
              }}
              value={rerunRadio}
            >
              <Space direction="vertical">
                <Radio value={1}>
                  使用上次任务参数重跑
                </Radio>
                <Radio value={2}>
                  指定Offset Time位置重跑
                </Radio>
              </Space>
            </Radio.Group>
            {rerunRadio === 2 ? (
              <div className="rerun-offset-time">
                {kafkaSourceTables
                  && kafkaSourceTables.map((item, index) => (
                    <Form.Item
                      label={item}
                      labelAlign="right"
                    >
                      <DatePicker
                        value={tableTimes[index] && tableTimes[index].time ? moment(tableTimes[index].time, 'YYYY-MM-DD HH:mm:ss') : undefined}
                        format="YYYY-MM-DD HH:mm:ss"
                        disabledDate={(current) => current && current > moment().endOf('day')}
                        onChange={(time, data) => {
                          const tableTime = [...tableTimes]
                          tableTime[index] = {
                            table: item,
                            time: data,
                          }
                          this.setState({
                            tableTimes: tableTime,
                          })
                        }}
                        disabledTime={() => ({
                          disabledHours: () => this.range(0, 24).splice(4, 20),
                          disabledMinutes: () => this.range(30, 60),
                          disabledSeconds: () => [55, 56],
                        })}
                        showTime={{
                          defaultValue: moment('00:00:00', 'HH:mm:ss'),
                        }}
                      />
                    </Form.Item>
                  ))}
              </div>
            ) : null}
          </div>
        </Modal>
        <Modal
          destroyOnClose
          title="续跑任务"
          confirmLoading={this.state.confirmLoading}
          visible={this.state.runShow}
          cancelText="取消"
          okText="确定"
          disabled={!savepoint}
          onOk={() => {
            this.realtimeRunningContinue()
          }}
          onCancel={() => {
            this.setState({
              runShow: false,
            })
          }}
          footer={[
            // 定义右下角 按钮的地方 可根据需要使用 一个或者 2个按钮
            <Button
              onClick={() => {
                this.setState({
                  runShow: false,
                })
              }}
            >
              取消
            </Button>,
            <Button
              type="primary"
              disabled={!savepoint}
              loading={this.state.confirmLoading}
              onClick={() => {
                this.realtimeRunningContinue()
              }}
            >
              确定
            </Button>,
          ]}
        >
          <div className="real-time-modal">
            <Alert
              message="续跑，任务将恢复至停止前的状态继续运行，若存在启停策略，将恢复自动启停"
              type="warning"
            />
            <br />
            <Radio.Group
              onChange={(e) => {
                this.setState({
                  runRadio: e.target.value,
                })
              }}
              disabled={!savepoint}
              value={runRadio}
            >
              <Space direction="vertical">
                <Radio value={1}>
                  通过SavePoint恢复并续跑（上次保存时间：
                  {savepoint ? savepoint.time : ''}）
                </Radio>
                <Radio value={2}>
                  通过CheckPoint恢复并续跑
                </Radio>
              </Space>
            </Radio.Group>
            <p>
              {runRadio === 2 ? (
                <Select
                  allowClear
                  showSearch
                  style={{ width: '300px' }}
                  filterOption={(input, option) => option.props.title
                    .toLowerCase()
                    .indexOf(input.toLowerCase()) >= 0}
                  value={checkPoint}
                  placeholder="请选择时间"
                  onChange={(value) => {
                    this.setState({
                      checkPoint: value,
                    })
                  }}
                >
                  {point && point.map((item, k) => (
                    <Option title={item.time} key={k} value={item.point}>
                      {item.time}
                    </Option>
                  ))}
                </Select>
              ) : null}
            </p>
          </div>
        </Modal>
      </div>
    )
  }
}

export default Operation
